package org.client.otdr;

import framework.mashup.LatLng;


public class LocationCalculator {
	private static final double EARTH_R = 6378.137;
	private LatLng[] nodes;

	public LocationCalculator(LatLng[] nodes) {
		this.nodes = nodes;
	}
	
	public LatLng getLatLng(Double distance) {
		for (int i = 0; i < nodes.length-1; i++) {
			if (distance < getDistance(i)) {
				Double sub = distance - getDistance(i);
				return getLatLng(sub, i);
			}
		}
		return new LatLng(0.0, 0.0);
	}


	private LatLng getLatLng(Double sub, int index) {
		double dist = getSpan(index);
		double ratio = sub / dist;
		double latDiff = nodes[index].lat - nodes[index - 1].lat;
		double lngDiff = nodes[index].lng - nodes[index - 1].lng;
		
		return new LatLng(nodes[index].lat + latDiff * ratio, nodes[index].lng + lngDiff * ratio);
	}

	private Double getDistance(int index) {
		Double ret = 0.0;
		for (int i = 1; i <= index ; i++) {
			ret += getSpan(i);
		}
		return ret;
	}

	private Double getSpan(int index) {
		double latInRad = Math.PI / 180 * (nodes[index].lat - nodes[index-1].lat);
		double lngInRad = Math.PI / 180 * (nodes[index].lng - nodes[index-1].lng);
		double ns = EARTH_R * latInRad;
		double ew = EARTH_R * Math.cos(Math.PI / 180 * nodes[index].lat) * EARTH_R * lngInRad;
		double dist = Math.sqrt(Math.pow(ew, 2) + Math.pow(ns, 2));
		return dist;
	}
}
